﻿using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Net;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Windows;

namespace JSON.App.Accelerator
{
    public class JsonViewModel1 : BaseEntity
    {
        #region Bindable Properties

        // TODO: Set the collection type to the appropriate object deserialized from.  This is
        //       the data type that the UI will data bind to
        private ObservableCollection<Result> _results;
        public ObservableCollection<Result> Results
        {
            get { return _results; }
            private set
            {
                if (value != _results)
                {
                    _results = value;
                    NotifyPropertyChanged("Results");
                }
            }
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// This is the callback method for the <see cref="GetData"/> method./>
        /// </summary>
        /// <param name="asynchronousResult">The asynchronous result.</param>
        private void GetDataResponseCallback(IAsyncResult asynchronousResult)
        {
            var request = (HttpWebRequest)asynchronousResult.AsyncState;
            var response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);

            using (var streamReader = new StreamReader(response.GetResponseStream()))
            {
                var resultString = streamReader.ReadToEnd();
                using (var stream = new MemoryStream(Encoding.Unicode.GetBytes(resultString)))
                {
                    var jsonSerializer = new DataContractJsonSerializer(typeof(RootObject));
                    var resultObject = (RootObject)jsonSerializer.ReadObject(stream);

                    // TODO: Set SearchResults to the appropriate object deserialized from
                    //       the JSON results
                    Deployment.Current.Dispatcher.BeginInvoke(
                        () => Results = resultObject.SearchResponse.Phonebook.Results);
                }
            }
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Invokes a web call and retrieves data in JSON format.
        /// </summary>
        public void GetData()
        {
            // TODO: Set the base URL to the web page returning the JSON-formatted data
            const string baseUrl = "http://api.bing.net/json.aspx";

            // TODO: The following example utilizes the bing JSON services.  If you are following
            //       along with this example, you can obtain your bing API ID here: 
            //       http://msdn.microsoft.com/en-us/library/dd251020.aspx
            const string bingAppId = "{Enter your bing APP ID here...}";

            // TODO: Format the service URI to include any necessary parameters.  The following 
            //       example is based on the bing Phonebook Request search API...
            var uri =
                string.Format(
                    "{0}?AppId={1}&Version=2.0&Market=en-US&Query=Coffee&Sources=phonebook&latitude=33.8563&longitude=-118.1232",
                    baseUrl, bingAppId);

            // Setup the HttpWebRequest that will be used to invoke the call to the service
            var webRequest = (HttpWebRequest)WebRequest.Create(uri);

            // Invoke the service call asynchronously.  The JSON-formatted data will be retrieved via
            // the callback method specified below.
            webRequest.BeginGetResponse(GetDataResponseCallback, webRequest);
        }

        #endregion
    }
}